package com.dq.service.sys.user.impl;

import com.dq.context.Constant;
import com.dq.controller.in.request.UserSchedulingRequest;
import com.dq.controller.in.user.SysUserQuery;
import com.dq.domain.base.impl.BaseDaoImpl;
import com.dq.domain.sys.section.SysSection;
import com.dq.exception.customException.AdminException;
import com.dq.controller.in.user.BossUserQuery;
import com.dq.controller.in.base.BaseAdminQuery;
import com.dq.domain.org.Org;
import com.dq.domain.sys.role.SysRole;
import com.dq.domain.sys.role.SysUserRole;
import com.dq.domain.sys.user.user.BossUser;
import com.dq.domain.sys.user.user.base.SysUser;
import com.dq.repository.BaseRepositories;
import com.dq.service.sys.user.BossUserService;
import com.dq.service.sys.user.SysUserRoleService;
import com.dq.validator.ValidatorUtils;
import com.dq.validator.group.AddGroup;
import com.dq.vo.Vo;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author liuhui
 * @date 2019/12/3 0003 10:59:48
 */
@Service
public class BossUserServiceImpl extends BaseRepositories implements BossUserService {
    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Override
    public List<BossUser> list(BossUserQuery bossUserQuery) throws AdminException {
        Map<String, Object> query = createQuery(bossUserQuery);

        return dao.find(dao.query2Hql(BossUser.class, query), query);
    }
    @Override
    public Long count(BossUserQuery bossUserQuery) throws AdminException {
        Map<String, Object> query = createQuery(bossUserQuery);

        return dao.count(dao.count2Hql(BossUser.class, query), query);
    }
    public Map<String, Object> createQuery(BossUserQuery bossUserQuery){
        Map<String, Object> query = bossUserQuery.parseMap();

        if(StringUtils.isNotEmpty(bossUserQuery.getUsername())){
            query.put("username" + BaseDaoImpl.likeSqlStr, BaseAdminQuery.likeSql(bossUserQuery.getUsername()));
            query.remove("username");
        }
        if(StringUtils.isNotBlank(bossUserQuery.getUserRealcName())) {
            query.put("userRealcName" + BaseDaoImpl.likeSqlStr, BaseAdminQuery.likeSql(bossUserQuery.getUserRealcName()));
            query.remove("userRealcName");
        }

        return query;
    }

    /**
     * 根据角色集合, 获取用户列表
     * @param sysUserQuery
     * @return
     */
    @Override
    public List<BossUser> getBossUserListByRoles(SysUserQuery sysUserQuery, int... index) {
        List<String> roleCodes = getUserRoleCodes(index);
        List<SysUserRole> list = sysUserRoleService.list(sysUserQuery, roleCodes);

        List<BossUser> returnList = new ArrayList<>();
        for (SysUserRole userRole : list) {
            if (!(userRole.getSysUser() instanceof BossUser)) {
                throw new AdminException("门店用户角色,非bossuser类型");
            }
            BossUser bossUser = (BossUser) userRole.getSysUser();
            returnList.add(bossUser);
        }
        return returnList;
    }
    @Override
    public long getBossUserCountByRoles(SysUserQuery sysUserQuery, int... index) {
        return sysUserRoleService.count(sysUserQuery, getUserRoleCodes(index));
    }

    private List<String> getUserRoleCodes(int... index) {
        List<String> roleCodes = new ArrayList<>();
        if(index != null && index.length > 0) {
            for (int i : index) {
                roleCodes.add(Constant.ROLE_CODE_LIST.get(i));
            }
        }
        return roleCodes;
    }

    /**
     * 获取 负责 本门店 的所有boss
     */
    @Override
    public List<BossUser> getBossByOrg(Org org) {
        List<BossUser> bossUsers = new ArrayList<>();

        // 获取 所有boss
        List<String> list = getUserRoleCodes(0, 3);
        List<SysUserRole> sysUserList = sysUserRoleRepository.findBySysRoleCodeIn(list);
        for (SysUserRole userRole : sysUserList) {
            BossUser bossUser = (BossUser) userRole.getSysUser();
            if (userRole.getSysRole().getCode().equals(Constant.ROLE_CODE_LIST.get(0))) {
                // 顶级boss
                bossUsers.add(bossUser);
            } else {
                // 负责本区域 门店 的子BOSS
                // 负责区域包括门店属于城市
                if(StringUtils.isNotBlank(org.getCity()) && StringUtils.isNotBlank(bossUser.getCity())) {
                    if (org.getCity().equals(bossUser.getCity())) {
                        bossUsers.add(bossUser);
                    }
                }
            }
        }

        return bossUsers;
    }

    /**
     * 获取用户所有角色 集合
     * @param user
     * @return
     */
    @Override
    public List<SysRole> getRolesByUser(SysUser user) {
        List<SysRole> roles = new ArrayList<>();

        Map<String, Object> query = new HashMap<>(16);
        query.put("sysUser_id", user.getId());
        List<SysUserRole> annexes = dao.find(dao.queryAdminHql(SysUserRole.class, query), query);

        for (SysUserRole annex : annexes) {
            roles.add(annex.getSysRole());
        }

        return roles;
    }

    /**
     * 获取 用户所有角色 code 集合
     * @param user
     * @return
     */
    @Override
    public List<String> getRoleCodesByUser(SysUser user) {
        List<String> roleCodeList = new ArrayList<>();

        List<SysRole> roles = getRolesByUser(user);
        for (SysRole role : roles) {
            roleCodeList.add(role.getCode());
        }

        return roleCodeList;
    }

    /**
     * boss 子账号添加 逻辑
     * 同时保存 角色用户关联表
     * @param bossUserAdd
     * @return
     * @throws AdminException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BossUser saveBossUserSon(BossUser bossUserAdd) throws AdminException {
        if(StringUtils.isBlank(bossUserAdd.getProvince()) || StringUtils.isBlank(bossUserAdd.getCity())) {
            throw new AdminException("负责区域为空");
        }
        String password = bossUserAdd.getPassword();
        bossUserAdd.setPassword(sysUserService.getPassword(password));

        // boss子账号 角色
        Map<String, Object> query = new HashMap<>(16);
        query.put("code", Constant.ROLE_CODE_LIST.get(3));
        List<SysRole> roles = dao.find(dao.query2Hql(SysRole.class, query), query);
        if(roles == null || roles.size() <= 0) {
            throw new AdminException("子账号角色获取异常");
        }

        bossUserAdd = initObject(bossUserAdd);
        dao.saveOrModify(bossUserAdd);

        SysUserRole userRole = new SysUserRole();
        userRole.setSysUser(bossUserAdd);
        userRole.setSysRole(roles.get(0));
        userRole = sysRoleService.initObjectUserRole(userRole);
        dao.saveOrModify(userRole);

        return bossUserAdd;
    }

    /**
     * BossUser 对象初始化, 验证手机号是否存在
     */
    @Override
    public BossUser initObject(BossUser bossUser) throws AdminException {
        objectWhere(bossUser);

        if(StringUtils.isNotBlank(bossUser.getMobile())) {
            BossUser byMobile = bossUserRepository.findByDeletedFalseAndMobileAndStatus(bossUser.getMobile(), BossUser.Status.on);
            if(byMobile != null) {
                throw new AdminException("手机号已存在");
            }
        }

        ///
//        if(bossUser.getSection() == null) {
//            SysSection numberOne = sysSectionService.getNumberOne();
//            bossUser.setSection(numberOne);
//        }

        SysUser user = sysUserService.getUser();
        bossUser.setCreateUser(user);
        bossUser.setUpdateUser(user);

        if(bossUser.getStatus() == null) {
            bossUser.setStatus(SysUser.Status.on);
        }

        return bossUser;
    }

    private void objectWhere(BossUser bossUser) throws AdminException {
        if(StringUtils.isBlank(bossUser.getUserRealcName())) {
            throw new AdminException("用户真实姓名为空");
        }
        if(StringUtils.isBlank(bossUser.getUsername())) {
            throw new AdminException("用户 账号 为空");
        }
        if(StringUtils.isBlank(bossUser.getPassword())) {
            throw new AdminException("用户 密码 为空");
        }
        if(bossUser.getSection() == null) {
            throw new AdminException("所属部门或门店为空");
        }
    }

    @Override
    public BossUser update(BossUser bossUser) throws AdminException {
        objectWhere(bossUser);

        SysUser sysUser = sysUserRepository.findByUsername(bossUser.getUsername());
        if (null != sysUser && !sysUser.getId().toString().equals(bossUser.getId().toString())) {
            throw new AdminException("该账号已存在");
        }
        if(StringUtils.isNotBlank(bossUser.getMobile())) {
            BossUser byMobile = bossUserRepository.findByDeletedFalseAndMobileAndStatus(bossUser.getMobile(), BossUser.Status.on);
            if(byMobile != null) {
                if(!byMobile.getId().toString().equals(bossUser.getId().toString())) {
                    throw new AdminException("手机号已存在");
                }
            }
        }

        if(bossUser.getDeleted()) {
            bossUser.setUsername(String.valueOf(System.currentTimeMillis()));
        }
        SysUser user = sysUserService.getUser();
        bossUser.setUpdateUser(user);

        bossUserRepository.save(bossUser);

        return bossUser;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BossUser save(BossUser bossUser) throws AdminException {
        // 对象初始化, 验证手机号是否存在
        bossUser = initObject(bossUser);

        SysUser queryUser = sysUserRepository.findByUsername(bossUser.getUsername());
        if(null!=queryUser){
            throw new AdminException("登录账号已存在");
        }

        bossUser.setPassword(sysUserService.getPassword(bossUser.getPassword()));
        bossUser.setStaffUserStatus(BossUser.StaffUserStatus.on);

        ValidatorUtils.validateEntity(bossUser, AddGroup.class);

        return sysUserRepository.save(bossUser);
    }

    @Override
    public Gson getGson() {
        // 过滤掉声明为 protcted 的变量
        return new GsonBuilder().setExclusionStrategies(new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes f) {
                // 过滤掉字段名
                return "createUser".equals(f.getName()) || "updateUser".equals(f.getName()) || "shopManager".equals(f.getName()) || "provincialManager".equals(f.getName());
            }
            @Override
            public boolean shouldSkipClass(Class<?> clazz) {
                //过滤掉 类名包含 Bean的类
                return clazz.getName().contains("Bean");
            }
        }).create();
    }

    @Override
    public Vo userScheduling(UserSchedulingRequest userSchedulingRequest) throws AdminException {
        BossUser staffUser = dao.get(BossUser.class,userSchedulingRequest.getId());
        if(staffUser == null){
            throw new AdminException("员工异常");
        }
        if(userSchedulingRequest.getEndTime() == null || "".equals(userSchedulingRequest.getEndTime())){
            throw new AdminException("下班时间不能为空");
        }
        if(userSchedulingRequest.getStartTime() == null || "".equals(userSchedulingRequest.getStartTime())){
            throw new AdminException("上班时间不能为空");
        }
        staffUser.setStartTime(userSchedulingRequest.getStartTime());
        staffUser.setEndTime(userSchedulingRequest.getEndTime());
        bossUserRepository.save(staffUser);
        return new Vo(HttpStatus.OK);
    }

    @Override
    public Vo dismiss(Long id) throws AdminException {
        BossUser staffUser = dao.get(BossUser.class,id);
        if(staffUser == null){
            throw new AdminException("员工异常");
        }
        if(staffUser.getStaffUserStatus().name.equals(BossUser.StaffUserStatus.on.name)) {
            staffUser.setStaffUserStatus(BossUser.StaffUserStatus.off);
            staffUser.setLeaveTime(System.currentTimeMillis());
        }else {
            staffUser.setStaffUserStatus(BossUser.StaffUserStatus.on);
        }
        bossUserRepository.save(staffUser);
        return new Vo(HttpStatus.OK);
    }

    @Override
    public Vo transfer(Long id, Long orgId) throws AdminException {
        BossUser staffUser = dao.get(BossUser.class,id);
        if(staffUser == null){
            throw new AdminException("员工异常");
        }
        SysSection section = dao.get(SysSection.class,orgId);
        if(section == null){
            throw new AdminException("转移门店异常");
        }
        staffUser.setSection(section);
        bossUserRepository.save(staffUser);
        return new Vo(HttpStatus.OK);
    }
}
